package com.example.permissionsystem1_1.system.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.permissionsystem1_1.common.util.RspResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.CoyoteInputStream;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 身份认证+权限url控制+超管拦截
 */
@Slf4j//此注解可以直接使用日志对象来进行日志打印
//@Component
public class AuthAndFunctionFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest=(HttpServletRequest)request;
        HttpServletResponse httpServletResponse=(HttpServletResponse)response;
        String url=httpServletRequest.getServletPath();
        log.debug("url:"+url);
        if(url==null||"".equals(url)){//路径为空,返回错误信息
            authAndFunctionFailedRspBuild(response,RspResult.URL_ERROR);
            return;
        }
        //0.白名单放行
        if(whiteUrlListCheck(url)){//白名单路径,直接放行
            chain.doFilter(request,response);
            return;
        }
        //1.进行身份认证
        Long userId=(Long)(httpServletRequest.getSession().getAttribute("userId"));
        if(userId==null){//未登录状态
            authAndFunctionFailedRspBuild(response,RspResult.NOLOGIN);
            return;
        }
        //2.对当前url进行功能权限的判断
        if(!functionUrlsCheck(httpServletRequest)){//没有权限,直接阻止并返回提示信息
            authAndFunctionFailedRspBuild(response,RspResult.NOFUNCTION);
            return;
        }
//        //3.判断是否是对超管角色或admin账号进行操作的接口访问:如果是,则阻止;如果不是,则放行
//        if(supperManageOperationCheck(httpServletRequest)){
//            authAndFunctionFailedRspBuild(response,RspResult.SUPER_PROHIBIT);
//            return;
//        }
        chain.doFilter(request,response);
    }

    //本类的工具方法
    /**
     * 构建接口访问被禁止后的响应数据
     * @param response
     */
    private void authAndFunctionFailedRspBuild(ServletResponse response,RspResult rspResult) throws IOException {
        String jsonStr=JSON.toJSONString(rspResult);//关键
//        JSONObject JSONRspResult = JSON.parseObject(jsonStr);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = response.getWriter();
        out.append(jsonStr);
    }

    /**
     * 判断当前接口url是否在白名单上
     * @param url
     * @return
     */
    private boolean whiteUrlListCheck(String url){
        if(Pattern.matches(".*\\.(js|css|gif|jpg|ico|png)$", url)||
            Pattern.matches("^/swagger.*", url)||
            Pattern.matches(".*\\.(woff2)$", url)||
            "/csrf".equals(url)||"/".equals(url)||"/v2/api-docs".equals(url)||
            "/userInfo/userLogout".equals(url)||
            "/userInfo/userLogin".equals(url)){
            return true;
        }
        return false;
    }

    /**
     * 功能权限判断
     * @param httpServletRequest
     * @return
     */
    private boolean functionUrlsCheck(HttpServletRequest httpServletRequest){
        List<String> functionUrls=(List<String>)(httpServletRequest.getSession().getAttribute("functionUrls"));
        if(functionUrls==null||functionUrls.size()<=1){
            //用户至少有一个登录权限,而登录接口又并不需要权限判断,所以权限列表只有1个的时候表示该用户肯定没有其他url接口的操作权限:所以也要阻止访问
            return false;
        }
        String url=httpServletRequest.getServletPath();
        Integer flag=0;
        for (String functionUrl:functionUrls) {
            if(url.equals(functionUrl)){//有此权限,放行
                flag=1;
                break;
            }
        }
        if(flag==0){//无此权限
            return false;
        }
        return true;
    }

//    /**
//     * 判断是否是对超管角色和admin账号进行操作的接口访问
//     * @param httpServletRequest
//     */
//    private boolean supperManageOperationCheck(HttpServletRequest httpServletRequest) throws IOException {
//        ServletInputStream servletInputStream=httpServletRequest.getInputStream();
//        StringBuilder content = new StringBuilder();
//        byte[] b = new byte[1024];
//        int lens = -1;
//        while ((lens = servletInputStream.read(b)) > 0) {
//            content.append(new String(b, 0, lens));
//        }
//        String strcont = content.toString();// 内容
//        JSONObject JSONobject=JSONObject.parseObject(strcont);
////        servletInputStream.r
//
//        //用户-查看
//        if(httpServletRequest.getServletPath().equals("/userInfo/selectById")&&
//                Long.valueOf(String.valueOf(JSONobject.get("id"))).equals(1l)){
//            return true;
//        }
//        //用户-修改
//        if(httpServletRequest.getServletPath().equals("/userInfo/updateById")&&
//                Long.valueOf(String.valueOf(JSONobject.get("id"))).equals(1l)){
//            return true;
//        }
//        //用户-删除
//        if(httpServletRequest.getServletPath().equals("/userInfo/deleteById")&&
//                Long.valueOf(String.valueOf(JSONobject.get("id"))).equals(1l)){
//            return true;
//        }
//        //角色-查看
//        if(httpServletRequest.getServletPath().equals("/roleInfo/selectById")&&
//                Long.valueOf(String.valueOf(JSONobject.get("id"))).equals(1l)){
//            return true;
//        }
//        //角色-修改
//        if(httpServletRequest.getServletPath().equals("/roleInfo/updateById")&&
//                Long.valueOf(String.valueOf(JSONobject.get("id"))).equals(1l)){
//            return true;
//        }
//        //角色-删除
//        if(httpServletRequest.getServletPath().equals("/roleInfo/deleteById")&&
//                Long.valueOf(String.valueOf(JSONobject.get("id"))).equals(1l)){
//            return true;
//        }
//        //部门用户-查看
//        if(httpServletRequest.getServletPath().equals("/departmentUser/selectAllDepartmentsByUserId")&&
//                Long.valueOf(String.valueOf(JSONobject.get("userId"))).equals(1l)){
//            return true;
//        }
//        //部门用户-分配
//        if(httpServletRequest.getServletPath().equals("/departmentUser/setDepartmentUserRelation")&&
//                Long.valueOf(String.valueOf(JSONobject.get("userId"))).equals(1l)){
//            return true;
//        }
//        //用户角色-查看
//        if(httpServletRequest.getServletPath().equals("/userRole/selectAllRolesByUserId")&&
//                Long.valueOf(String.valueOf(JSONobject.get("userId"))).equals(1l)){
//            return true;
//        }
//        //用户角色-分配
//        if(httpServletRequest.getServletPath().equals("/userRole/setUserRoleRelation")&&
//                (Long.valueOf(String.valueOf(JSONobject.get("userId"))).equals(1l)||
//                Long.valueOf(String.valueOf(JSONobject.get("roleId"))).equals(1l))){
//            return true;
//        }
//        //角色功能-查看
//        if(httpServletRequest.getServletPath().equals("/roleFunction/selectAllFunctionsByRoleId")&&
//                Long.valueOf(String.valueOf(JSONobject.get("roleId"))).equals(1l)){
//            return true;
//        }
//        //角色功能-分配
//        if(httpServletRequest.getServletPath().equals("/roleFunction/setRoleFunctionRelation")&&
//                Long.valueOf(String.valueOf(JSONobject.get("roleId"))).equals(1l)){
//            return true;
//        }
//        return false;
//    }


}
